from flask import Flask, render_template, request, send_from_directory, jsonify
import os
import uuid
import comtypes.client
from werkzeug.utils import secure_filename
import time
import pythoncom
import traceback
import logging

# 配置日志
logging.basicConfig(level=logging.DEBUG, 
                   format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['OUTPUT_FOLDER'] = 'output'
app.config['ALLOWED_EXTENSIONS'] = {'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'}
app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024  # 限制上传文件大小为50MB

# 确保上传和输出目录存在
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['OUTPUT_FOLDER'], exist_ok=True)

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']

def convert_to_pdf(input_file, output_file):
    """使用comtypes将Office文档转换为PDF"""
    logger.info(f"开始转换文件: {input_file} 到 {output_file}")
    pythoncom.CoInitialize()  # 初始化COM
    
    file_ext = input_file.rsplit('.', 1)[1].lower()
    
    try:
        if file_ext in ['doc', 'docx']:
            # Word转PDF
            logger.info("使用Word转换文档")
            word = comtypes.client.CreateObject('Word.Application')
            word.Visible = False
            doc = word.Documents.Open(input_file)
            doc.SaveAs(output_file, FileFormat=17)  # 17代表PDF格式
            doc.Close()
            word.Quit()
        elif file_ext in ['xls', 'xlsx']:
            # Excel转PDF
            logger.info("使用Excel转换文档")
            excel = comtypes.client.CreateObject('Excel.Application')
            excel.Visible = False
            wb = excel.Workbooks.Open(input_file)
            wb.ExportAsFixedFormat(0, output_file)  # 0代表PDF格式
            wb.Close()
            excel.Quit()
        elif file_ext in ['ppt', 'pptx']:
            # PowerPoint转PDF
            logger.info("使用PowerPoint转换文档")
            powerpoint = comtypes.client.CreateObject('Powerpoint.Application')
            powerpoint.Visible = False
            presentation = powerpoint.Presentations.Open(input_file)
            presentation.ExportAsFixedFormat(output_file, 2)  # 2代表PDF格式
            presentation.Close()
            powerpoint.Quit()
        logger.info("文件转换成功")
        return True
    except Exception as e:
        logger.error(f"转换错误: {e}")
        logger.error(traceback.format_exc())
        return False
    finally:
        pythoncom.CoUninitialize()  # 清理COM

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def upload_file():
    logger.info("收到文件上传请求")
    if 'file' not in request.files:
        logger.warning("没有上传文件")
        return jsonify({'success': False, 'error': '没有上传文件'})
    
    file = request.files['file']
    
    if file.filename == '':
        logger.warning("未选择文件")
        return jsonify({'success': False, 'error': '未选择文件'})
    
    if file and allowed_file(file.filename):
        # 生成安全的文件名
        filename = secure_filename(file.filename)
        logger.info(f"处理文件: {filename}")
        
        # 添加唯一标识符，避免文件名冲突
        unique_filename = f"{str(uuid.uuid4())}_{filename}"
        
        # 保存原始文件
        file_path = os.path.join(os.path.abspath(app.config['UPLOAD_FOLDER']), unique_filename)
        file.save(file_path)
        logger.info(f"文件已保存到: {file_path}")
        
        # 创建输出PDF的路径
        pdf_filename = f"{os.path.splitext(unique_filename)[0]}.pdf"
        pdf_path = os.path.join(os.path.abspath(app.config['OUTPUT_FOLDER']), pdf_filename)
        
        # 转换文件
        if convert_to_pdf(file_path, pdf_path):
            logger.info(f"文件转换成功: {pdf_path}")
            return jsonify({
                'success': True, 
                'filename': pdf_filename,
                'download_url': f'/download/{pdf_filename}'
            })
        else:
            logger.error("文件转换失败")
            return jsonify({'success': False, 'error': '文件转换失败'})
    
    logger.warning("不支持的文件类型")
    return jsonify({'success': False, 'error': '不支持的文件类型'})

@app.route('/download/<filename>')
def download_file(filename):
    return send_from_directory(app.config['OUTPUT_FOLDER'], filename, as_attachment=True)

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'),
                               'favicon.ico', mimetype='image/vnd.microsoft.icon')

if __name__ == '__main__':
    app.run(debug=True) 